<!--
    by: yuanbiao 2021年08月18日
    name: x-modal
    notes:
-->
<template>
  <div :class="[ prefixCls, `${prefixCls}-${size}` ]">
    <transition enter-active-class="animated bounceInDown" leave-active-class="animated bounceOutUp">
      <div v-show="visible" :class="`${prefixCls}__content`" :style="contentStyles">
        <div :class="`${prefixCls}__header`" v-show="showHeader">
          <slot name="header">{{title}}</slot>
          <div v-if="closable" :class="`${prefixCls}__close`" @click="close">
            <i class="xvu-iconfont xvu-close"></i>
          </div>
        </div>
        <div :class="`${prefixCls}__body`">
          <slot name="default"></slot>
        </div>
        <div :class="`${prefixCls}__footer`" v-show="showFooter">
          <slot name="footer">
            <x-button :size="size" @click="cancel">{{cancelText}}</x-button>
            <x-button type="primary" :loading="buttonLoading" :size="size" @click="ok">{{okText}}</x-button>
          </slot>
        </div>
      </div>
    </transition>
    <transition enter-active-class="animated fadeIn" leave-active-class="animated fadeOut">
      <div v-show="visible" :class="`${prefixCls}__mask`" @click="maskClose"></div>
    </transition>
  </div>
</template>

<script>
import xButton from '@/components/button/index.js'

const prefixCls = 'x-modal'
export default {
  name: 'x-modal',
  components: {
    xButton
  },
  props: {
    value: {
      type: Boolean,
      default: false
    },
    closable: {
      type: Boolean,
      default: true
    },
    maskClosable: {
      type: Boolean,
      default: true
    },
    title: {
      type: String
    },
    width: {
      type: [Number, String],
      default: 520
    },
    height: {
      type: [Number, String],
      default: 320
    },
    styles: {
      type: Object
    },
    okText: {
      type: String,
      default: '确定'
    },
    cancelText: {
      type: String,
      default: '取消'
    },
    loading: {
      type: Boolean,
      default: false
    },
    size: {
      type: String,
      default: 'default'
    },
    showHeader: {
      type: Boolean,
      default: true
    },
    showFooter: {
      type: Boolean,
      default: true
    },
  },
  data() {
    return {
      prefixCls: prefixCls,
      visible: this.value,
      buttonLoading: false,
    }
  },
  computed: {
    contentStyles () {
      let width = parseInt(this.width)
      let height = parseInt(this.height)
      let sizeStyle = {
        width: width <= 100 ? `${width}%` : `${width}px`,
        height: `${height}px`,
      }
      let customStyle = this.styles || {}
      return {
        ...sizeStyle,
        ...customStyle,
      }
    },
  },
  watch: {
    value (n) {
      this.visible = n
    },
  },
  mounted () {
    document.addEventListener('keydown', this.EscClose)
  },
  beforeDestroy () {
    document.removeEventListener('keydown', this.EscClose)
  },
  methods: {
    close () {
      this.visible = false
      this.$emit('input', false)
      this.$emit('close')
    },
    EscClose (e) {
      if (this.visible && this.closable) {
        if (e.keyCode === 27) this.close()
      }
    },
    maskClose () {
      if (this.maskClosable) this.close()
    },
    cancel () {
      this.close()
    },
    ok () {
      if (this.loading) {
        this.buttonLoading = true
      } else {
        this.visible = false
        this.$emit('input', false)
      }
      this.$emit('ok')
    },
  }
}
</script>
